/*
 * Class with static methods which can write object to the file system or read from it.
 */
package filesystem;

import java.io.*;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

/**
 *
 * @author ArieS
 */
public class FileWorker {

    /**
     * Save ModelItem's object in the file system.
     *
     * @param hm map, where keys are names of the attributes and values are
     * values of the attributes.
     *
     * @param path path to file.
     * @throws IOException
     *
     * @param header header of the xml file
     */
    public static void saveFile(Map hm, String path, String header)
            throws IOException {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.newDocument();
            Element title = doc.createElement(header);
            for (Object o : hm.entrySet()) {
                Map.Entry me = (Map.Entry) o;
                Element element = doc.createElement(String.valueOf(me.getKey()));
                element.appendChild(doc.createTextNode(String.valueOf(me.getValue())));
                title.appendChild(element);
               
            }
            doc.appendChild(title);
            Transformer t = TransformerFactory.newInstance().newTransformer();
            t.setOutputProperty(OutputKeys.METHOD, "xml");
            t.setOutputProperty(OutputKeys.INDENT, "yes");
            FileOutputStream fos = new FileOutputStream(path); 
            t.transform(new DOMSource(doc), new StreamResult(fos));
            fos.close();

        } catch (ParserConfigurationException | DOMException | TransformerFactoryConfigurationError | IllegalArgumentException | FileNotFoundException | TransformerException ex) {
            throw new IOException(ex);
        }

    }

    /**
     * Load file from the file system.
     *
     * @param path path to file.
     * @return map, where keys are names of the attributes and values are values
     * of the attributes.
     *
     * @throws IOException
     */
    public static Map loadFile(String path)
            throws IOException {
        SAXParserFactory factory;
        SAXParser parser;
        SAXHandler handler;
        try {
            factory = SAXParserFactory.newInstance();
            parser = factory.newSAXParser();
            handler = new SAXHandler();
            parser.parse(path, handler);
        } catch (ParserConfigurationException | SAXException | IOException ex) {
            throw new IOException(ex);
        }
        return handler.getResult();
    }

    /**
     * Delete file from the file system.
     *
     * @param path path to file.
     * @throws IOException
     */
    public static void deleteFile(String path)
            throws IOException {
        File fl = new File(path);
        fl.delete();
    }

    /**
     * Load headers from files with this extension.
     *
     * @param path path to file.
     * @param extension file's extension.
     * @return headers in array of the Strings
     */
    public static String[] getHeaders(String path, String extension) {
        new File(path).mkdirs();
        File fl = new File(path);
        return fl.list(new DirFilter(extension));
    }

    public static OutputStream mapToStream(Map map) {
        return null;
        //TODO release
    }
}

class DirFilter implements FilenameFilter {

    String afn;

    DirFilter(String afn) {
        this.afn = afn;
    }

    @Override
    public boolean accept(File dir, String name) {
        String f = new File(name).getName();
        return f.indexOf(afn) != -1;
    }
}